Reflection & Annotations
Reflection & Annotations for Automation Testing (How Frameworks Work Internally)β
Context (Why this topic exists NOW)β
By now, your automation framework:
- runs reliably in CI
- uses TestNG/JUnit annotations
- supports listeners, retries, and reports
A natural question appears: How do frameworks discover tests and execute them without explicit calls?
Selenium does not provide this. Java Reflection and Annotations explain how automation frameworks work internally.
What Selenium Cannot Do (The Gap)β
Selenium can:
- execute browser commands
Selenium cannot:
- discover test classes dynamically
- invoke methods without direct calls
- read metadata like annotations
- build execution flow automatically
This logic is handled entirely by Java.
What Reflection & Annotations Add (The Fix)β
They allow frameworks to:
- inspect classes at runtime
- detect annotations
- invoke methods dynamically
- control execution flow without hardcoding
In simple words:
Selenium executes steps.
Reflection decides what steps to execute.
What Are Annotations (Automation View)β
Annotations are metadata, not logic.
Examples you already use:
@Test@BeforeMethod@AfterMethod@DataProvider
They tell the framework:
- what a method represents
- when it should be executed
How TestNG/JUnit Use Annotations (Conceptual)β
At runtime:
- Framework scans classes
- Finds methods with
@Test - Determines execution order
- Invokes methods using reflection
You never call test methods manually.
What Is Reflection (Automation View)β
Reflection allows Java to:
- inspect classes, methods, fields at runtime
- call methods dynamically
- access metadata (annotations)
Example:
Method method = testClass.getDeclaredMethod("loginTest");
method.invoke(instance);
Frameworks use this extensively.
Why Automation Engineers Should Careβ
Reflection explains:
- why annotations work
- how listeners hook into execution
- how retry logic intercepts failures
- how custom frameworks are built
You donβt write reflection daily, but you benefit from understanding it.
Custom Annotations (Awareness Level)β
Example:
@Retention(RUNTIME)
@Target(METHOD)
public @interface SmokeTest {
}
Used to:
- tag tests
- filter execution
- build custom runners
Mostly framework-level, not test-level.
Where Reflection Is Used in Automationβ
- Test discovery
- Listener execution
- Retry analyzers
- Dependency injection (light)
- Reporting hooks
Selenium does none of this.
When NOT to Use Reflectionβ
β Writing test logic with reflection
β Over-engineering frameworks
β Using reflection where normal code works
Reflection is powerful but dangerous if misused.
Common Mistakesβ
- Treating annotations as executable code
- Overusing reflection unnecessarily
- Debugging annotation issues without understanding lifecycle
- Trying to modify private framework internals
Best Practices (Automation-Approved)β
- Understand reflection conceptually
- Let frameworks handle reflection
- Use annotations as intended
- Avoid custom reflection-heavy logic unless necessary
Interview Notesβ
- What are annotations?
- How TestNG/JUnit discover tests
- Role of reflection in frameworks
- Difference between compile-time and runtime behavior
- Why reflection is powerful but risky
Summary (Human Understanding)β
Annotations describe what a method is. Reflection decides when and how to run it.
Frameworks feel magical because reflection is working behind the scenes.